package top.littleze.aiattendance.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import top.littleze.aiattendance.dao.AttendanceLogEntityMapper;
import top.littleze.aiattendance.dao.AttendanceStudentEntityMapper;
import top.littleze.aiattendance.dto.StudentAttendanceReportDTO;
import top.littleze.aiattendance.entity.AttendanceLogEntity;
import top.littleze.aiattendance.service.StudentService;
import top.littleze.aiattendance.utils.page.Reply;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author ZhaoGengze
 * @Date 2021/7/9 11:39
 */

@Service
@Slf4j
public class StudentServiceImpl implements StudentService {

    @Autowired
    AttendanceStudentEntityMapper studentEntityMapper;
    @Autowired
    AttendanceLogEntityMapper logEntityMapper;

    /**
     * 是否上传照片
     * @param studentId
     * @return
     */
    @Override
    public Reply<Void> updateInfo(String studentId) {
        // 1. 判断是否已上传照片
        boolean flag = studentEntityMapper.hasUpdatePhoto(studentId);
        log.info("是否上传照片flag: {}", flag);
        // 2. 已上传
        if (flag) {
            return Reply.success(901, "已上传照片");
        }
        // 3. 未上传
        if (!flag) {
            return Reply.success(901, "未上传照片");
        }

        return Reply.failuer(500, "服务端错误");
    }

    /**
     * 学生签到
     * @param request
     * @return
     */
    @Override
    public Reply<Void> checkin(AttendanceLogEntity request) {
        // TODO 人脸识别
        Date date = new Date();
        request.setCheckinTime(date);
        request.setCheckin(true);
        // TODO 其余逻辑
        logEntityMapper.insertSelective(request);
        return Reply.success();
    }

    /**
     * 出勤报告
     * @param studentId
     * @return
     */
    @Override
    public Reply<List<StudentAttendanceReportDTO>> attendanceReport(String studentId) {
        // 查询某课程所有的出勤记录
        List<AttendanceLogEntity> logEntities = logEntityMapper.queryAttendanceReport(studentId);
        List<String> courseList = logEntities.stream().map(o -> o.getCourseId()).distinct().collect(Collectors.toList());

        Map<String, List<AttendanceLogEntity>> map = logEntities.stream().collect(Collectors
                .groupingBy(AttendanceLogEntity::getCourseId));
        Map<String, List<AttendanceLogEntity>> attendanceTimesMap = logEntities.stream()
                .filter(o -> o.getCheckin() != null && o.getCheckin() == true)
                .collect(Collectors.groupingBy(AttendanceLogEntity::getCourseId));
        Map<String, List<AttendanceLogEntity>> askForLeaveTimesMap = logEntities.stream()
                .filter(o -> o.getAskForLeave() != null && o.getAskForLeave() == true)
                .collect(Collectors.groupingBy(AttendanceLogEntity::getCourseId));
        Map<String, List<AttendanceLogEntity>> notAttendanceTimesMap = logEntities.stream()
                .filter(o -> o.getCheckin() != null && o.getCheckin() == false)
                .collect(Collectors.groupingBy(AttendanceLogEntity::getCourseId));
        for (Map.Entry<String, List<AttendanceLogEntity>> entry : map.entrySet()) {
            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
        }
        List<StudentAttendanceReportDTO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(logEntities)) {
            result.addAll(courseList.stream().map(o -> {
                StudentAttendanceReportDTO dto = new StudentAttendanceReportDTO();
                dto.setCourseId(o);
                dto.setCourseName(map.get(o).get(0).getCourseName());
                Integer attendanceTimes = attendanceTimesMap.get(o) == null ? 0 : attendanceTimesMap.get(o).size();
                dto.setAttendanceTimes(attendanceTimes);
                dto.setAskForLeaveTimes(askForLeaveTimesMap.get(o) == null ? 0 : askForLeaveTimesMap.get(o).size());
                Integer notAttendanceTimes = notAttendanceTimesMap.get(o) == null ? 0 : notAttendanceTimesMap.get(o).size();
                dto.setNotAttendanceTimes(notAttendanceTimes);
                Integer sum = attendanceTimes + notAttendanceTimes;
                if (sum == 0) {
                    dto.setAttendanceRate(0.0);
                } else {
                    dto.setAttendanceRate(attendanceTimes / (sum * 1.0));
                }
                return dto;
            }).collect(Collectors.toList())
            );
        }

        return Reply.success(result, result.size());
    }
}
